#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys, re, os
import time
from datetime import date
from sheepomatic_io import Csv_file,Sheep_brief_file,Shepherd_brief_file
from sheepomatic import Sheep,Shepherd
import sheepomatic

class Match_info:
   @classmethod
   def print_info(cls,sheep_list,shepherd_list,couples):
      """Prints statistics about the sheep-shepherd match solution
  
      Parameters:
      sheep_list -- sheep object list
      shepherd_list -- shepherd obbject list
      couples -- list of tuples with sheep-shepherd pairs
      """
      # mail -> sheep/shepherd hashes
      sheep_hash = {}
      for sheep in sheep_list:
         sheep_hash[sheep.mail] = sheep
      shepherd_hash = {}
      for shepherd in shepherd_list:
         shepherd_hash[shepherd.mail] = shepherd
      # happy shepherds
      used_shepherds = set([])
      happy_count = 0
      happy_shepherds = set([])
      for sheep_key,shepherd_key,happy,weight in couples:
         used_shepherds.add(shepherd_key)
         if int(happy) > 0:
            happy_count += 1
            happy_shepherds.add(shepherd_key)
      happy_pair_rate = float(float(happy_count) / float(len(couples)))
      happy_shepherd_rate = float(float(len(happy_shepherds)) / float(len(used_shepherds)))
      print "Happy pairs:",str(happy_count)+"/"+str(len(couples)),str(happy_pair_rate*100),"%"
      print "Happy shepherds:",str(len(happy_shepherds))+"/"+str(len(used_shepherds)),str(happy_shepherd_rate*100),"%"
      # same faculty
      assigned_sheep = set([])
      same_faculty_count = 0
      for sheep_key,shepherd_key,happy,weight in couples:
         assigned_sheep.add(sheep_key)
         if sheep_hash[sheep_key].faculty == shepherd_hash[shepherd_key].faculty:
            same_faculty_count += 1
      same_faculty_rate = float(float(same_faculty_count) / float(len(couples)))
      print "\nSame faculties:",str(same_faculty_count)+"/"+str(len(couples)),str(same_faculty_rate*100),"%"
      # date statistics
      positive_diff = 0
      negative_diff = 0
      positive_count = 0
      zero_count = 0
      negative_count = 0
      diff_freq = {}
      for sheep_key,shepherd_key,happy,weight in couples:
         diff = (sheep_hash[sheep_key].arrival_date - shepherd_hash[shepherd_key].ava_date).days
         if diff not in diff_freq:
            diff_freq[diff] = 0
         diff_freq[diff] += 1
         if diff > 0:
            positive_diff += diff
            positive_count +=1
         elif diff < 0:
            negative_diff += diff
            negative_count +=1
         else:
            zero_count += 1
      print "\nDates:"
      print "positive total diff:",str(positive_diff),";",str(positive_count),"pairs"
      print "negative total diff:",str(negative_diff),";",str(negative_count),"pairs"
      print "Date diff distribution:"
      for diff in sorted(diff_freq, reverse=True):
         print str(diff)+":",str(diff_freq[diff])
      # shepherd load
      shepherd_load = {}
      for shepherd in shepherd_list:
         shepherd_load[shepherd.mail] = 0
      for sheep_key,shepherd_key,happy,weight in couples:
         shepherd_load[shepherd_key] += 1
      print "\nShepherds not fully loaded:"
      for shepherd in shepherd_list:
         if shepherd.capacity > shepherd_load[shepherd.mail]:
            print shepherd.mail+"\t"+str(shepherd_load[shepherd.mail])+"/"+str(shepherd.capacity)+"\t"+\
                  shepherd.ava_date.isoformat()+"\t"+",".join(shepherd.langs)
      # sheep not assigned
      print "\nSheep not assigned:"
      for sheep in sheep_list:
         if sheep.mail not in assigned_sheep:
            date = sheep.arrival_date.isoformat()
            print sheep.mail+"\t"+date+"\t"+",".join(sheep.langs)

   @classmethod
   def read_couples(cls,filename):
      """Reads sheep-shepherd couples and returns them as a tuple list"""
      f = open(filename, 'r')
      couple_list = []
      #
      for line in f.readlines():
         line = line.strip()
         couple_list.append(tuple(line.split(",")))
      f.close()
      return couple_list

def main(args):
    """Prints statistics about the sheep-shepherd match solution

    Parameters:
    sheep_file -- sheep brief file with normalized values
    shepherd_file -- shepherd brief file with normalized values
    pairing_file -- file with sheep-shepherd couples
    """
    # review parameters
    sheep_normed_file = args[0]
    shepherd_normed_file = args[1]
    pairing_file = args[2]
    # read sheep + shepherds
    sheep_list = Sheep_brief_file.read_sheep_brief_file(sheep_normed_file)
    shepherds_list = Shepherd_brief_file.read_shepherd_brief_file(shepherd_normed_file)
    # read file with couples
    couples = Match_info.read_couples(pairing_file)
    # print info
    Match_info.print_info(sheep_list,shepherds_list,couples)

if __name__ == '__main__':
    args = sys.argv[1:]
    if len(args) == 3:
       main(args)
    else:
       print >> sys.stderr, "Wrong number of parameters."
       print >> sys.stderr, "Usage:"
       print >> sys.stderr, "match_info.py sheep_brief_file shepherd_brief_file couples_file"
       sys.exit(1)
